// returning false will cause the bot to quit
// returning a string will return that string to the server
// returning an array will return any strings in the array to the server


var app = new Object();
app.defaults = new Object();
app.defaults.nick = "SMIrc";
app.defaults.port = "6667";
app.defaults.nicks = [ "nicks2", "nick3" ];

app.connections = new Object();
app.connections["undernet"] = { 
    host: "irc.undernet.org",
    username: "smirc", realname: "SpiderMonkey IRC",
    nick: "SMIrc"
};

app.room_options = { "#room1": { nodeop: 1, nomodechange: 1 },
		     "#pixie": { nodeop: 1, nomodechange: 1 },
		     "#opers": { nodeop: 1, nomodechange: 1 },
		     "#room8": { modes: "ntNT" }
};

function get_username ( connection_name ) {
    if ( app.connections[connection_name] &&
	 app.connections[connection_name]["username"] ) {
	return app.connections[connection_name]["username"];
    } else {
	return app.defaults.username;
    }
}

function get_realname ( connection_name ) {
    if ( app.connections[connection_name] &&
	 app.connections[connection_name]["realname"] ) {
	return app.connections[connection_name]["realname"];
    } else {
	return app.defaults.realname;
    }
}

function on_undernet_connected () {
    // Set the current nick, will be used by the src.mynick parameter
    // in future callbacks.
    var mynick = app.defaults.nick;	
    if ( app.connections["undernet"] && app.connections["undernet"]["nick"] ) {
	mynick = app.connections["undernet"]["nick"];
	app.connections["undernet"]["current_nick"] = mynick;
    } else {
	app.defaults.current_nick = mynick;
    }
    
    return [ 
	    "user " + get_username ( "undernet" ) + " 0 * :" 
	    + get_realname ( "undernet" ),
	    "nick " + mynick
	    ];
}

function on_undernet_PRIVMSG ( src, params, trailer ) {
    // if this is a /msg to me
    if ( params[0] == src.mynick && trailer && trailer.length > 0 ) {
	// quit 
	if ( trailer.search ( /^quit a_password$/ ) >= 0 ) return false;

	// this stuff is unrealircd specific
	var res;
	if ( res = trailer.match ( /^addword a_password ([\w@]{4,4}\w*)/ ) )
	    return [
		    "notice #opers :addword " + res[1],
		    "spamfilter + cp block 0 Spam " + res[1]
	    ];
	if ( res = trailer.match ( /^chanop\s+a_password\s+\+g\s+(.*?)\s*$/ ) ) {
	    app.glinenick = res[1];
	    return [ 
		    "whois " + res[1],
		    "whowas " + res[1] 
	    ];
	}
	
	// a chanops command to op/deop
	if ( res = trailer.match (/^chanop\s+a_password\s+([-+])o\s+([^\s]+)\s+#(.*?)\s*$/) )
	    if ( res[1] == "+" ) 
		return [
			"NOTICE #opers :CHANOPS TO " + res[2]  + " in #" +  res[3],
			"mode #" + res[3] + " +o " + res[2]
			];
	    else if ( res[1] == "-" ) {
		var cmd = "mode #" + res[3] + " -o " + res[2];
		return [
			"NOTICE #opers :" + cmd,
			cmd
		];
	    }
    }

    // report domain names or ip addresses
    if ( params[0] != "#opers" &&
	 trailer.search ( /\.com|\.net|\.org|\.info|\.uk\.co|@|\d?\d?\d\.\d?\d?\d\.\d?\d?\d\.\d?\d?\d/ ) >= 0 ) {
	return "PRIVMSG #opers :" + src.nick + " in " + params[0] + " said " + trailer;
    }
}

function on_NICK ( src, params, trailer ) {
    if ( src.nick == src.mynick ) 
	if ( app.connections[ src.connection ] )
	    app.connections["undernet"]["current_nick"] = trailer;
	else 
	    app.defaults.current_nick = trailer;
}

function on_PING ( src, params, trailer ) {
    return "PONG :" + trailer;
}

function on_004 ( src, params, trailer ) {
    // consider yourself registered here
    // join the rooms to monitor
    return [ 
	    "mode " + src.mynick + " -h",
	    "mode " + src.mynick + " +s +S",
	    "join #smirc"
	    ];
}

function on_311 ( src, params, trailer ) {
    // result of WHOIS

    // this is a chanop +g
    if ( app.glinenick && app.glinenick == params[1] ) {
	app.glinenick = null;
	return "gline +*@" + params[3] + " 3600 :Spam";
    }
}

function on_314 ( src, params, trailer ) {
    // result of WHOWAS

    // this is a chanop +g
    if ( app.glinenick && app.glinenick == params[1] ) {
	app.glinenick = null;
	return "notice #opers :gline +*@" + params[3] + " 3600 :Spam";
    }
}

function on_322 ( src, params, trailer ) {
    // reply to LIST
    var room = params[1];
    var num_in_room = params[2];

    // if there is only one in the room I don't go in or
    // if I have joined (because there was more than one in it) I am
    // the last one so leave.
    if ( num_in_room == 1 && room.match ( "#opers" ) == null ) {
	return "part " + room + " :Closing the room";
    }
    var rep = [
	       "join " + params[1],   // join each room
	       "mode " + params[1],   // send mode for each room
	       "names " + params[1],  // send a NAMES for each room
	       "topic " + params[1]   // request the room topic
    ];
    
    return rep;
}

function on_324 ( src, params, trailer ) {
    // reply to MODE
    if ( app.room_options[params[1]] && app.room_options[params[1]]["nomodechange"] != null )
	return;
    var modes = "ntT";
    if ( app.room_options[params[1]] && app.room_options[params[1]]["modes"] != null )
	modes = app.room_options[params[1]]["modes"];

    if ( params[2].match ( modes ) == null ) {
	var oldmodes = params[2].replace ( /^\+/, "" );
	return [
		"notice #opers reseting modes in " + params[1],
		"mode " + params[1] + " -" + oldmodes,
		"mode " + params[1] + " +" + modes
	];
    }
}

function on_332 ( src, params, trailer ) {
    // reply to TOPIC
    // set topic to null
    if ( trailer && trailer.length > 0 ) 
	return [ 
		"notice #opers reseting topic in " + params[1],
		"topic " + params[1] + " :"
	];
}

function on_353 ( src, params, trailer ) {
    // reply to NAMES
    var room_type = params[1]; // @: secret, *: private, =: others (public)
    var room = params[2];
    if ( app.room_options[room] && app.room_options[room]["nodeop"] != null ) return;
    var nick = trailer.split ( " " );
    var resp = new Array();
    for ( var i = 0, j = nick.length; i < j; i++ ) {
	var r = nick[i].match ( /^@(.+)/ );
	if ( r != null ) {
	    var cmd = "mode " + room + " -o " + r[1];
	    resp.push ( "notice #opers :" + cmd,
			cmd );
	}
    }
    return resp;
}

function on_473 ( src, params, trailer ) {
    // reset the mode on an invite only channel I tried to enter
    return [ 
	    "mode " + params[1] + " -i", 
	    "join " + params[1] 
    ];
}

function on_433 ( src, params, trailer ) {
    // nick already in use
}

